#ifndef	UTIL_H
#define	UTIL_H

#pragma once

#include "ImgPre.h"
#include "HOG.h"

#include <stdio.h>
#include <vector>

#define MAX_HYPOTHESIS 10

using namespace std;
using namespace cv;
using namespace ImgPre;
using namespace HOG;
using namespace OpLib;

namespace Util
{

	/*! Initialize the working object: added scaled images and extracted HOG features
	* @param obj WorkingObject
	*/
	void initTree(WorkingObject *obj)
	{
		addScaledImagesToWorkingObject(obj);
		vector<HierElement *> scaled_images = obj->getLowerElements();
		for (int i=0; i< scaled_images.size(); i++)
		{
			// HOGS erstellen
			extractHOGFeatures(((WorkImage *)scaled_images[i]));
		}
	}

	/*! Extract MAX_HYPOTHESIS random hypothesis from the WorkingObject
	* @param obj WorkingObject
	* @return vector<Mat> vector with MAX_HYPOTHESIS hog arrays
	*/
	vector<Mat> getRandomHypothesis(WorkingObject* obj)
	{
		vector<HierElement *> scaled_images = obj->getLowerElements();
		vector<Mat> hypothesis_vector;

		srand (time(NULL));

		for(int i=0; i<MAX_HYPOTHESIS; i++)
		{
			// random number in the range 0 to scaled_images.size()-1
			int random_number = rand() % scaled_images.size();
			WorkImage* w_image = ((WorkImage *)scaled_images[random_number]);

			createSlidingWindows(w_image);
			vector<HierElement *> sliding_window_vector = w_image->getLowerElements();
			if(sliding_window_vector.size() != 0)
			{
				random_number = rand() % sliding_window_vector.size();

				Mat hypothesisI = ((WindowedHOG*)sliding_window_vector[random_number])->windowed_hog;

				hypothesis_vector.push_back(hypothesisI);
			}
			else
			{
				printf("%s\n", (obj->filename).c_str());
			}
		}
		return hypothesis_vector;
	}

	/*!
	* Shows an image with
	* @param obj Working object
	* @param n draws the first n found_hits objects
	*/
	void drawClassifiedImage(WorkingObject * obj, int n){
		namedWindow("Image");
		Mat img= obj->source_image;
		int i = n;
		if(obj->found_hits.size() < i)
			i = obj->found_hits.size();

		for (std::vector<WeightedRect>::iterator it= obj->found_hits.begin(); it!=obj->found_hits.begin()+i; ++it){
			printf("Drawing struct: %i, %i\n", (*it).rect.x, (*it).rect.y);
			rectangle(img, (*it).rect, Scalar(0, 255, 0));
			stringstream numberString;
			numberString << it->weight;   
			string number = numberString.str();
			putText(img, number , Point(it->rect.x, (it->rect.y)+20), 2, 0.3, Scalar(0, 255, 0), 1, 16);
		}
		imshow("Image", img);
		waitKey();
	}
}

#endif